/*********************************************************************************
 *      Copyright:  (C) 2020 Tang Zhiqiang<t_zhiqiang@163.com>
 *                  All rights reserved.
 *
 *       Filename:  client_list.c
 *    Description:  This file list struct 
 *                 
 *        Version:  1.0.0(05/04/2020)
 *         Author:  Tang Zhiqiang <t_zhiqiang@163.com>
 *      ChangeLog:  1, Release initial version on "05/04/2020 09:01:31 PM"
 *                 
 ********************************************************************************/

#include<stdlib.h>
#include<stdio.h>
#include <unistd.h>
#include <string.h>
#include "client_list.h"


/* 功能：   创建一个单链表(尾插法) */
/* 参数：   无 */
/* 返回值： 链表的头指针 */
client_list_t* create_list()
{
        client_list_t *new_node = (client_list_t *)malloc(sizeof(client_list_t) );
        if (new_node==NULL)
        {
            return NULL;
        }
        new_node->next = NULL;
        print_test;
        //printList(temp);
        return new_node;    //返回头指针
}


/* 功能：   遍历并打印链表value值 */
/* 参数：   链表的头指针 */
/* 返回值： 无 */
void print_list(client_list_t *head)
{
    client_list_t *p = head;
    while (p != NULL)
    {
        printf("%d\n", p->fd);
        p = p->next;
    }
    printf("\n");
}

/* 功能：   向单链表的尾部添加一个值为val的节点 */ 
/* head:    链表头指针 */
/* fd:      结点的value值 */
/* 返回值： 返回新插入的节点指针 */
/* 注意：   若不带头节点，需要传二级指针，改变头指针 */
client_list_t* add_list_to_tail(client_list_t *head, int fd)  //  head形参为引用类型
{
    print_test;
    client_list_t *new_node = (client_list_t *)malloc(sizeof(client_list_t) );
    if (new_node == NULL)
    {
        //申请内存失败
        print_test;
        return NULL;
    }
    print_test;

    /* 初始化链表节点 */
    memset(new_node, 0, sizeof(client_list_t));  //结构体指针为NULL，其实也是0 
    new_node->fd = fd;          //文件描述符作为遍历数组的标识不能被初始化

    client_list_t *p = head;    //创建一个指针指向头节点，防止更改头指针
    //判断链表头指针是否为空
    if (NULL == p) 
    {
        return NULL;
    }
    print_test;
    // 链表非空时
    while (p->next != NULL) //  找到尾节点的前驱节点
    {
        p = p->next;
        //print_test;
    }
    p->next = new_node;  //  插入新节点
    //print_test;
    
    return new_node;
}


/* 功能：   从单链表中删除一个值为val的节点 */
/* 参数：   头节点指针和要删除值为value的结点 */
/* 返回值： 无     */
/* 注意：   若不带头节点，需要传二级指针，改变头指针 */
void delete_node(client_list_t *head, int fd)  //  head形参为引用类型
{
    if (NULL == head)             //  链表为空
    {
        printf("List is empty.\n");
        return;
    }
    client_list_t *delete_node = NULL;  //  记录要删除的节点
                          
    while (head->next != NULL && head->next->fd != fd)
    {
        head = head->next;            //  找到要删除的节点的前驱节点
        //print_test;
    }
    if (head->next != NULL && head->next->fd == fd)
    {
        delete_node = head->next;       //  记录要删除的节点 
        head->next = head->next->next;  //  删除值为val的节点
        print_test;
    }
    
    if (delete_node != NULL)
    {
        free(delete_node);  
        delete_node = NULL;
        print_test;
    }
    print_test;
}

/* 功能：   销毁整个链表 */
/* head：   传入链表头指针的指针 */
/* 返回值： 无 */
/* 注意：销毁链表需要传二级指针，改变头指针 */
void destory_list(client_list_t **head)
{
    while (*head)
    {
        client_list_t *p_free = *head;   //找到头指针
        *head = (*head)->next;       //跳到下一个结点
        free(p_free);
    }
}


/* 功能：   根据value值查找链表结点 */
/* head：   传入链表头节点*/
/* fd:      节点的value值 */
/* 返回值： 空指针则未找到节点，否则返回当前value的结点指针 */
client_list_t *find_node(client_list_t *head, int fd)
{   
    //判断链表是否为空
    if (head == NULL)
    {
        print_test;
        return NULL;
    }
    //head = head->next;      //跳过头节点
    while(head != NULL && head->fd != fd)
    {
        head = head->next;
        //print_test;
    }
    print_test;
    return head;     //找到节点直接返回
}


